Laravel 嵌套事务

Laravel 中嵌套事务的处理逻辑与回滚

1. 数据库保存点 (Savepoints)

对于支持保存点的数据库(如:MySQL、PostgreSQL),Laravel 会利用这个特性来实现“嵌套事务”的行为。

DB::transaction(function () {
    // 外层事务操作
    DB::table('users')->insert(['name' => 'Alice']);

    DB::transaction(function () {
        // 内层事务操作 (会创建一个保存点)
        DB::table('orders')->insert(['user_id' => 1, 'product' => 'Laptop']);

        // 假设这里发生异常
        // throw new \Exception('订单创建失败');

    }); // 如果内层有异常,会回滚到这个保存点

    // 外层事务继续 (如果内层回滚,这里的数据可能保持不变,取决于回滚到保存点)
    DB::table('logs')->insert(['message' => 'User Alice added']);

}); // 如果外层有异常,整个事务回滚

2. 扁平化事务 (Flat Transactions)

对于不支持保存点的数据库(如:NoSQL 数据库),Laravel 会将所有嵌套的 $DB::transaction() 调用视为单一的扁平化事务

3. 总结

特性 / 行为 支持保存点的数据库 (MySQL, PostgreSQL) 不支持保存点的数据库 (或扁平化模式)
嵌套调用 创建数据库保存点 增加事务深度计数器,不执行数据库命令
内部异常回滚 回滚到对应的保存点 (ROLLBACK TO SAVEPOINT) 整个事务完全回滚 (ROLLBACK)
外部异常回滚 整个事务完全回滚 (ROLLBACK) 整个事务完全回滚 (ROLLBACK)
提交 只有最外层事务成功,最终才 COMMIT 只有最外层事务成功,最终才 COMMIT